/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_RTP_H
#define MK_RTP_H
#include "MkRtpUtil.h"
#include "MkUtil/MkRwLock.h"

typedef MkFunction<void()> MkRtpClosedCallback;

typedef struct _rtp_sender_remoter
{
    MkRtpPacketCallback     RtpPacketCb;
    MkRtcpPacketCallback    RtcpPacketCb;
    MkRtpClosedCallback     RtpClosedCb;
    MkString                RtpRemoteHost;
    Uint16                  RtpRemotePort;
    Uint8                   Payload;
    Uint16                  SeqNum;
    Uint32                  TimeStamp;
    CMkTime                 LastRtcpActiveTime;
    MkRtpType               RtpType;
    Uint32                  Ssrc;
    Uint32                  SendPacketCount;
    Uint32                  RecvPacketCount;
    CMkTime                 CreateTime;
    _rtp_sender_remoter()
    {
        RtpClosedCb = nullptr;
        RtpPacketCb = nullptr;
        RtcpPacketCb = nullptr;
        SeqNum = 0;
        Ssrc = 0;
        SendPacketCount = 0;
        RecvPacketCount = 0;
        TimeStamp = 0;
        LastRtcpActiveTime = NowMkTime;
        CreateTime = LastRtcpActiveTime;
    }
}MkRtpRemoter;

class CMkTimer;
class MkApi CMkRtp
{
public:
    CMkRtp(CMkTimer* pTimer, BOOL bCheckRtcp = FALSE, Uint32 RtcpCheckTime = 10);
    virtual ~CMkRtp();

    Uint32 AddRtpRemoter(const Uint32& Ssrc, const MkRtpRemoter& Remoter);
    virtual Uint32 DeleteRemoter(const Uint32& Ssrc);
    Uint32 GetScore();
    CMkTimer* GetTimer() { return m_pTimer; }
    Uint32 GetRemoterSsrc(const MkString& RtpRemoteHost, Uint16 RtpRemotePort);
    Uint32 GetRemoter(const Uint32& Ssrc, MkRtpRemoter& Remoter);
    Uint32 GetSenderRemoter(const Uint32& Ssrc, const Uint32& TimeStamp, MkRtpRemoter& Remoter);
    Uint32 GetFirstRemoter(MkRtpRemoter& Remoter);
    Uint32 SendData(const Uint8* pData, Uint32 nDataLen, Uint32 Ssrc, Uint32 TimeStamp);
    Uint32 SendBuffer(const CMkBufferList& BufList, Uint32 Ssrc, Uint32 TimeStamp);
protected:
    Uint32 ParseRtpPacket(const CMkRtpPacket& RtpPacket, const MkString& SenderHost, const Uint16& SenderPort);
    Uint32 ParseRtcpPacket(const CMkRtcpPacket& RtcpPacket, const MkString& SenderHost, const Uint16& SenderPort);
    virtual Uint32 SendRtpPacket(const CMkRtpPacket& RtpPacket, const MkString& RemoteIp, Uint16 RemotePort) = 0;
    virtual Uint32 SendRtcpPacket(const CMkRtcpPacket& RtcpPacket, const MkString& RemoteIp, Uint16 RemotePort) = 0;
    virtual Uint32 Release() = 0;
#ifndef MkUt
private:
#else
public:
#endif
    void OnRtcpCheck();
private:
    Uint32                                      m_RtcpCheckTime;
    CMkRwLock                                   m_RemoterLock;
    MkUnorderedMap<Uint32, MkRtpRemoter>        m_MapRemoter;           //key rtp ssrc
    CMkTimer                                    *m_pTimer;
    MkString                                    m_RtcpCheckSession;
};

#endif //!MK_RTP_H